package com.celesea.configuration.ehcache;

import com.celesea.configuration.security.SsoUtil;
import com.celesea.configuration.security.bean.AuthorityUser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.stereotype.Component;

@Component
public class EhcacheProvider {

    private static Logger logger = LoggerFactory.getLogger(EhcacheProvider.class);
    private static final Long SSO_LOGIN_USER_TIME_STAMP_DEFAULT = -1L;

    private static final String SSO_LOGIN_USER_CACHE = "SsoLoginUserCache";
    private static final String SSO_LOGIN_USER_TIME_STAMP_CACHE = "SsoLoginUserTimeStampCache";

    @Value("${spring.security.ehcache.loginInfoCheckPeriod}")
    private Long loginInfoCheckPeriod;

    @Autowired(required = false)
    private CacheManager cacheManager;

    /**
     * 清空本地最后与redis登录信息同步对比的最后时间戳
     *
     * @param loginSessionId
     */
    public void clearUserTimeStamp(String loginSessionId) {
        String redisUserKey = SsoUtil.getUpdateTimeKey(loginSessionId);
        if (cacheManager == null) {
            logger.info("eccache is not support：{}..................", redisUserKey);
            return;
        }
        logger.info("清除Ehcache缓存用户登录信息最后更新时间:{}", redisUserKey);
        Cache cache = cacheManager.getCache(SSO_LOGIN_USER_TIME_STAMP_CACHE);
        cache.put(redisUserKey, SSO_LOGIN_USER_TIME_STAMP_DEFAULT);
    }

    /**
     * 获取本地最后与redis登录信息同步对比的最后时间戳
     *
     * @param loginSessionId
     */
    public Long getUserTimeStamp(String loginSessionId) {
        String redisUserKey = SsoUtil.getUpdateTimeKey(loginSessionId);
        if (cacheManager == null) {
            logger.info("eccache is not support：{}..................", redisUserKey);
            return SSO_LOGIN_USER_TIME_STAMP_DEFAULT;
        }
        logger.info("通过Ehcache加载用户登录信息最后更新时间:{}", redisUserKey);
        Cache cache = cacheManager.getCache(SSO_LOGIN_USER_TIME_STAMP_CACHE);
        Cache.ValueWrapper value = cache.get(redisUserKey);
        if (value != null && value.get() != null && value.get() instanceof Long) {
            logger.info("Ehcache加载用户登录信息最后更新时间:{}", redisUserKey);
            return (Long) value.get();
        }
        logger.info("Ehcache不存在用户登录信息最后更新时间:{}", redisUserKey);
        return SSO_LOGIN_USER_TIME_STAMP_DEFAULT;
    }

    /**
     * 标记本地最后与redis登录信息同步对比的最后时间戳
     *
     * @param loginSessionId
     */
    public void cacheUserTimeStamp(String loginSessionId) {
        // 最后检查时间为当前时间戳
        Long updateTime = System.currentTimeMillis();
        String redisUserKey = SsoUtil.getUpdateTimeKey(loginSessionId);
        if (cacheManager == null) {
            logger.info("eccache is not support：{}..................", redisUserKey);
            return;
        }
        logger.info("通过Ehcache缓存用户登录信息最后更新时间:{}", redisUserKey);
        Cache cache = cacheManager.getCache(SSO_LOGIN_USER_TIME_STAMP_CACHE);
        cache.put(redisUserKey, updateTime);
        logger.info("通过Ehcache缓存用户登录信息最后更新时间:{}", redisUserKey);
    }

    public boolean enableSkipCheckLoginInfo(String loginSessionId) {
        Long updateTime = getUserTimeStamp(loginSessionId);
        if (updateTime == null || updateTime < 0) {
            return false;
        }
        Long timestamp = System.currentTimeMillis();
        if (loginInfoCheckPeriod == null || updateTime + loginInfoCheckPeriod > timestamp) {
            return true;
        }
        return false;
    }


    public AuthorityUser getUserDetailsFromCache(String loginSessionId) {
        try {
            String redisUserKey = SsoUtil.getLoginInfoKey(loginSessionId);
            if (cacheManager == null) {
                logger.info("eccache is not support：{}..................", redisUserKey);
                return null;
            }
            logger.info("通过Ehcache加载用户信息:{}", redisUserKey);

            Cache cache = cacheManager.getCache(SSO_LOGIN_USER_CACHE);
            Cache.ValueWrapper value = cache.get(redisUserKey);
            if (value != null && value.get() != null && value.get() instanceof AuthorityUser) {
                logger.info("Ehcache加载用户信息成功:{}", redisUserKey);
                return (AuthorityUser) value.get();
            }
            logger.info("Ehcache不存在用户信息:{}", redisUserKey);
        } catch (Exception e) {
            logger.error("Ehcache获取用户信息失败",e);
        }
        return null;
    }

    public void cacheUserDetails(String loginSessionId, AuthorityUser userDetails) {
        String redisUserKey = SsoUtil.getLoginInfoKey(loginSessionId);
        if (cacheManager == null) {
            logger.info("eccache is not support：{}..................", redisUserKey);
            return;
        }
        logger.info("通过Ehcache缓存用户信息:{}", redisUserKey);
        Cache cache = cacheManager.getCache(SSO_LOGIN_USER_CACHE);
        cache.put(redisUserKey, userDetails);
        logger.info("通过Ehcache缓存用户信息成功:{}", redisUserKey);
    }

    public void clearUserDetails(String loginSessionId) {
        String redisUserKey = SsoUtil.getLoginInfoKey(loginSessionId);
        if (cacheManager == null) {
            logger.info("eccache is not support：{}..................", redisUserKey);
            return;
        }
        logger.info("清除Ehcache缓存用户信息:{}", redisUserKey);
        Cache cache = cacheManager.getCache(SSO_LOGIN_USER_CACHE);
        cache.put(redisUserKey, null);
    }
}
